package com.fingard.startup;

import java.io.File;
import java.net.URL;
import java.net.URLDecoder;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Properties;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import com.fingard.FGBiz;
import com.fingard.io.FileHelper;
import com.fingard.text.StringHelper;

public class JavaClassMap {

	/**类名map*/
	private HashMap<String,String> classNameMap;
	public void load(){
		HashMap<String,String> map = new HashMap<String,String>();
		try {
			//fastjson安全模式加入JVM环境
			Properties properties = System.getProperties();
			properties.put("fastjson.parser.safeMode","true");
			System.setProperties(properties);
			String dspJar = FGBiz.DSPHOME+File.separator+"dsp.jar";
			String[] nameSpaces = new String[]{"com.fingard.dsp.web.page", "com.fingard.dsp.task.command"};//, "fingard.dsp.bank.directbank"
			ClassLoader loader = null;
			JarFile jarFile = null;
			for(int i=0;i<nameSpaces.length;i++){
				if(FileHelper.existFile(dspJar)){
					if(jarFile == null){
						jarFile = new JarFile(dspJar);
					}
					loadClassNameByJar(jarFile, map, nameSpaces[i]);
				}else{
					if(loader == null){
						loader = Thread.currentThread().getContextClassLoader();
					}
					String rPath = nameSpaces[i].replace(".", "/");
					URL webPage = loader.getResource(rPath);
					if(webPage != null){
						String mPath = URLDecoder.decode(webPage.getPath(), "utf-8");
						File mFile = new File(mPath);
						if(mFile.exists()){
							String mainDir = mFile.getAbsolutePath();
							loadClassNameByFile(mainDir, map, mainDir, nameSpaces[i]);
						}else{
							FGBiz.startLog.error(this.getClass().getName(), "文件"+mPath+"不存在");
						}
					}else{
						FGBiz.startLog.error(this.getClass().getName(), "ClassLoader.getResource("+rPath+")为null");
					}
				}
			}
		} catch (Exception ex) {
			FGBiz.startLog.exception(this.getClass().getName(), ex);
		}
		classNameMap = map;
		if(classNameMap.size() == 0){
			FGBiz.startLog.error(this.getClass().getName(), "加载的ClassName个数为"+classNameMap.size());
		}else{
			FGBiz.startLog.addToLimit(this.getClass().getName(), "加载的ClassName个数为"+classNameMap.size());
			FGBiz.startLog.addToLimitNoConsole(this.getClass().getName(), "加载的ClassName：\r\n"+this.getAllClassName());
		}
	}
	
	public String getClassByName(String pName){
		if(classNameMap !=null && classNameMap.containsKey(pName)){
			return classNameMap.get(pName); 
		}
		return null;
	}
	
	private HashMap<String,Class<?>> classMap;
	/**取得类Class<?>*/
	public Class<?> getJavaClass(String pName){
		if(classMap == null){//初始化classMap
			HashMap<String,Class<?>> map = new HashMap<String,Class<?>>();
			if(classNameMap !=null){
				for(String eachKey : classNameMap.keySet()){
					try{
						String className = classNameMap.get(eachKey);
						Class<?> tmpclass = Class.forName(className);
						map.put(eachKey, tmpclass);
					}catch(ClassNotFoundException ex){
						FGBiz.startLog.exception(getClass().getName(), ex);
					}catch(Throwable ex){
						FGBiz.startLog.exception(getClass().getName(), ex);
					}
				}
			}
			classMap = map;
		}
		if(classMap.containsKey(pName)){
			return classMap.get(pName);
		}
		return null;
	}
	
	public String getAllClassName(){
		StringBuilder sb = new StringBuilder();
		if(classNameMap !=null){
			for(String eachKey : classNameMap.keySet()){
				sb.append(classNameMap.get(eachKey)+"\r\n");
			}
		}
		return sb.toString();
	}
	
	/**根据文件查.class，递归方式，开发调试模式*/
	private void loadClassNameByFile(String pDir, HashMap<String,String> pMap, String pMain, String pNameSpace){
        File dirFile = new File(pDir);
        File[] files = dirFile.listFiles();
        for (File eachFile : files) {
            if (eachFile.isDirectory()) {
            	loadClassNameByFile(eachFile.getPath(), pMap, pMain, pNameSpace);
            } else {
            	String cName = eachFile.getAbsolutePath();
            	if(cName.endsWith(".class")){
            		cName = cName.replace(pMain, "").replace(File.separator, ".");
            		cName = StringHelper.trimStart(cName, ".");
            		cName = cName.substring(0, cName.lastIndexOf("."));
            		cName = pNameSpace + "." + cName;
            		pMap.put(cName.toLowerCase(), cName);
            	}
            }
        }
    }
	
	/**根据jar包查.class，.jar运行模式*/
	private void loadClassNameByJar(JarFile pJarFile, HashMap<String,String> pMap, String pNameSpace) {
		String findPath = pNameSpace.replace(".", "/");
		Enumeration<JarEntry> entrys = pJarFile.entries();
        while (entrys.hasMoreElements()) {
            JarEntry jarEntry = entrys.nextElement();
            String entryName = jarEntry.getName();
            if (entryName.endsWith(".class")) {
            	int idx = entryName.lastIndexOf("/");
            	String pckPath;
                if (idx >= 0) {
                	pckPath = entryName.substring(0, idx);
                } else {
                	pckPath = entryName;
                }
            	if (pckPath.startsWith(findPath)) {
                    String cName = entryName.replace("/", ".");
                    cName = cName.substring(0, entryName.lastIndexOf("."));
                    pMap.put(cName.toLowerCase(), cName);
                }
            }
        }
    }
}
